package hotel.callback.oversea.service.impl;

import hotel.callback.oversea.config.service.RedisService;
import hotel.base.oversea.constant.CallbackConstants;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.constant.enums.MessageEnums;
import hotel.base.oversea.service.impl.BaseServiceImpl;
import hotel.base.oversea.utils.DateUtil;
import hotel.base.oversea.utils.GsonUtils;
import hotel.base.oversea.utils.Result;
import hotel.base.oversea.utils.SendUtils;
import hotel.base.oversea.vo.meituan.response.goods.MtHotelGoodsCallbackVo;
import hotel.base.oversea.vo.meituan.response.goods.MtHotelGoodsPriceBaseDetailVo;
import hotel.callback.oversea.service.MtHotelCheckGoodsPriceService;
import hotel.callback.oversea.service.MtHotelGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class MtHotelCheckGoodsPriceServiceImpl extends BaseServiceImpl implements MtHotelCheckGoodsPriceService {
    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MtHotelGoodsService mtHotelGoodsService;

    /**
     * 校验某个 产品日期 是否发生改变
     * @param priceModels
     * @param thisHotelId
     * @param goodsId
     * @param hourStr
     * @param result
     * @param thisTimestampApi
     * @return
     */
    @Override
    public Map<String, MtHotelGoodsPriceBaseDetailVo> checkOneGoodsArrayDateChange(String todayOrYest, List<MtHotelGoodsPriceBaseDetailVo> priceModels, Integer thisHotelId, Integer goodsId, String hourStr, Result<Object> result, String thisTimestampApi, Integer fromJob){
        log.info("checkOneGoodsIdIsChange 进入 goodsId={},thisHotelId={},hourStr={},result={},thisTimestampApi={},priceModels={}",goodsId,thisHotelId,hourStr);
        //log.info("主动查询-美团接口-校验酒店产品 {}  hotel={} queryRoomPriceByOneHotelId循环产品当前该产品为售卖房型 existSale  into  hotel_goodsId={}",timestamp,hotelId,key);
        //key = 产品id  + 日期 ， value = 价格信息 --》 Map<String,MtHotelGoodsPriceBaseDetailVo>
        Map<String, MtHotelGoodsPriceBaseDetailVo> oneGoodsChangeAboutDatePriceMap = new HashMap<>();
        //每个产品有价格信息：返回的价格信息是数组，数组size大于1，因为上送的是日期为一个月
        if(null != priceModels && priceModels.size()>0){
            Integer returnThisHotelCompare = 0;
            //log.info("主动查询-美团接口-校验酒店产品 {} getChangeMonthGoodsIdsByOneHotelId hotel_goodsId={},priceModels={}",timestamp,key,GsonUtils.GsonString(priceModels));
            for (MtHotelGoodsPriceBaseDetailVo thisPriceVo:priceModels){
                //产品涉及多个价格组（30天30个日期价格），每个价格日志进行价格变更判断
                //查询mt_hotel_goods_price表（根据酒店产品价格日期得到唯一数据），没查询到就是价格发送改变
                Integer apiSalePrice = thisPriceVo.getSalePrice();
                Integer salePrice = thisPriceVo.getSalePrice();//最新美团售价
                if(new BigDecimal(salePrice).compareTo(new BigDecimal(5000))<0){
                    log.info("主动查询价格小于50，当前调整为50，hotelId={},goodsId={}",thisHotelId,goodsId);
                    salePrice = 5000;
                    thisPriceVo.setSalePrice(salePrice);
                }

                String ctrlPriceClose = (String)redisService.get("swmt_ctrl_price_hotels_close");
                Integer tj = null;
                if(ObjectUtils.isEmpty(ctrlPriceClose)){
                    tj = (Integer)redisService.hmGet(CommonConstants.SWITCH_JOIN_ACTIVE_HOTEL_LIST,thisHotelId);
                    if(!ObjectUtils.isEmpty(tj)){
                        log.info("主动查询调价酒店，进行追加金额：hotelId={},tj={}",thisHotelId,tj);
                    }
                }

                String date = thisPriceVo.getDate();//价格日期
                Integer subPrice = thisPriceVo.getSubPrice();//佣金价格
                Long days = DateUtil.dateDiff(DateUtil.getCurrTime(),"day",date,"yyyy-MM-dd");

                Integer redisStatusDays = (Integer)redisService.get(CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_STATUS_HEAD+thisHotelId+"_"+goodsId+"_"+date);//载入新一天时，可能堆积，若推送了价格还没推送房态携程也会开房，这时候会造成延时单
                if(ObjectUtils.isEmpty(redisStatusDays)){
                    log.info("主动查询价格 房态缓存为空,当前跳过该次价格判断等待下一轮 goodsId={},thisHotelId={},date={}",goodsId,thisHotelId,date);
                    continue;
                }

                /**
                 * 合理价推送判断
                 */
                String redisKeyExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_PRICE_HEAD+thisHotelId+"_"+goodsId+"_"+date;//美团异步推送的缓存酒店+产品+日期
                Integer has = (Integer)redisTemplate.opsForValue().get(redisKeyExpiDays);
                Boolean isChange = false;
                if(null != has && BigDecimal.valueOf(has).compareTo(new BigDecimal(salePrice))==0){
                    //一样，异步推送过不再主动推送
                }else{
                    if(!ObjectUtils.isEmpty(has) && new BigDecimal(salePrice).compareTo(new BigDecimal(has))>0){
                        log.info("主动价格涨价了推送returnThisHotelCompare=1hotelId={},goodsId={},date={}",thisHotelId,goodsId,date);
                        returnThisHotelCompare = 1;
                    }
                    Boolean returnTodo = true;
                    String checkGtPriceHourNot = (String)redisService.get("swmt_check_gt_price_hour_not");//多个时间段逗号隔开，当前设置为"00,01":在这段时间主动查询的价格不推送降价和上一次价格相比（当前暂时不对异步做处理，00,01这两个时间点异步是关闭的）
                    if(null != checkGtPriceHourNot && checkGtPriceHourNot.contains(hourStr)){
                        if(null != has && BigDecimal.valueOf(salePrice).compareTo(new BigDecimal(has))<0){
                            log.info("根据上一次价格，指定时间段涨价可推送，降价不推送 checkGtPriceHour={},hourStr={},thisHotelId={},goodsId={},date={}",checkGtPriceHourNot,hourStr,thisHotelId,goodsId,date);
                            returnTodo = false;
                        }
                    }

                    //5天变成售卖4天
                    String closeThisDateRedisNormal = (String)redisService.get("normal_close_this_date");//yyyy-MM-dd
                    if(!ObjectUtils.isEmpty(closeThisDateRedisNormal)){
                        //判断是否普通酒店
                        if(closeThisDateRedisNormal.equals(date)){
                            Boolean isVip = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_VIP,thisHotelId);
                            if(!isVip){
                                String redisKeyStatusExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_STATUS_HEAD+thisHotelId+"_"+goodsId+"_"+date;//美团异步推送的缓存酒店+产品+日期
                                Integer hasStatus = (Integer)redisTemplate.opsForValue().get(redisKeyStatusExpiDays);
                                if(null != hasStatus && hasStatus == 0){
                                    returnTodo = false;
                                }else{
                                    if(new BigDecimal(has).compareTo(new BigDecimal(salePrice))==0){//上一次价格和当前最新价格一样 则没有变化 不需要推送---》》》异步暂时不做这个判断 都过，只是要判断标准价-->特殊时间段做这个判断
                                        returnTodo = false;
                                    }
                                    if(returnTodo){
                                        if(null != has && BigDecimal.valueOf(salePrice).compareTo(new BigDecimal(has))<0){
                                            log.info("callback NORMAL 减少售卖天数该日降价不推送 checkGtPriceHour={},hourStr={},thisHotelId={},goodsId={},date={}",checkGtPriceHourNot,hourStr,thisHotelId,goodsId,date);
                                            returnTodo = false;
                                        }
                                    }
                                }
                            }
                        }
                    }else{
                        String closeThisDateRedisVip = (String)redisService.get("vip_close_this_date");//yyyy-MM-dd
                        if(!ObjectUtils.isEmpty(closeThisDateRedisVip)){
                            if(closeThisDateRedisVip.equals(date)){
                                //判断是否普通酒店
                                Boolean isVip = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_VIP,thisHotelId);
                                if(isVip){
                                    String redisKeyStatusExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_STATUS_HEAD+thisHotelId+"_"+goodsId+"_"+date;//美团异步推送的缓存酒店+产品+日期
                                    Integer hasStatus = (Integer)redisTemplate.opsForValue().get(redisKeyStatusExpiDays);
                                    if(null != hasStatus && hasStatus == 0){
                                        returnTodo = false;
                                    }else{
                                        if(new BigDecimal(has).compareTo(new BigDecimal(salePrice))==0){//上一次价格和当前最新价格一样 则没有变化 不需要推送---》》》异步暂时不做这个判断 都过，只是要判断标准价-->特殊时间段做这个判断
                                            returnTodo = false;
                                        }
                                        if(returnTodo){
                                            if(null != has && BigDecimal.valueOf(salePrice).compareTo(new BigDecimal(has))<0){
                                                log.info("callback VIP 减少售卖天数该日降价不推送 checkGtPriceHour={},hourStr={},thisHotelId={},goodsId={},date={}",checkGtPriceHourNot,hourStr,thisHotelId,goodsId,date);
                                                returnTodo = false;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if(returnTodo){
                        //上一次价格和当前不一样时判断合理价是否推送  has可能有值  也可能 为空
                        Integer libraryPriceBefore = null;
                        if(null == redisService.get("swmt_library_price_close")){
                            libraryPriceBefore = (Integer) redisService.get(MeituanConstants.REDIS_ONE_GOODS_PRICE_LIBRARY_NEW+thisHotelId+"_"+goodsId);
                        }
                        redisTemplate.opsForValue().set("compare_time_for_mt_callback_price_"+thisHotelId+"_"+goodsId+"_"+date, DateUtil.getCurrTime(),1, TimeUnit.HOURS);
                        if(null == libraryPriceBefore){
                            if(null != has){
                                log.info("进入比对 比例低价算法，判断价格是否推送");
                                Integer minPrice = 20000;//单位分
                                if(null != redisService.get("sw_price_check_change_min")){
                                    minPrice =(Integer) redisService.get("sw_price_check_change_min");
                                }

                                Double pro = 0.6;
                                if(null != redisService.get(CommonConstants.PRICE_CHECK_CHANGE_MIN_PRO)){//40
                                    pro =new BigDecimal((Integer) redisService.get("sw_price_check_change_min_pro")).multiply(new BigDecimal(0.01)).doubleValue();
                                }

                                if(new BigDecimal(salePrice).compareTo(new BigDecimal(minPrice))<=0 && new BigDecimal(has).multiply(new BigDecimal(pro)).compareTo(new BigDecimal(salePrice))>0){
                                    if(null == redisService.get("sw_not_push_price_ding_send_"+thisHotelId+"_"+goodsId+"_"+date+"_"+salePrice)){
                                        log.info("[JOB-PRICE-TASK][比例低价算法]主动查询价格可能异常最新价格="+salePrice+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+goodsId+"_"+date);//+" rpInfo="+ GsonUtils.GsonString(result)
                                        SendUtils.dingMsgNotLog("[JOB-PRICE-CHANGE-CHECK]主动查询价格变化浮动可能异常，人工确认 ", DateUtil.getCurrTime()+" 最新价格="+salePrice+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+goodsId+"_"+date+" 比例底价："+pro+"_"+minPrice, MessageEnums.genre.SWITCH_ORDER_ROOM_COMPARE_NOTIFY.getCode(),restTemplate);
                                        redisService.setUnit("sw_not_push_price_ding_send_"+thisHotelId+"_"+goodsId+"_"+date+"_"+salePrice,1,2L,TimeUnit.HOURS);
                                    }else{
                                        log.info("不再推钉钉[JOB-PRICE-TASK]主动查询价格可能异常最新价格="+salePrice+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+goodsId+"_"+date+" rpInfo="+ GsonUtils.GsonString(result));
                                    }
                                    //主动无变化日志 异步还是保存变化日志 虽然没有推送携程
                                    isChange = false;
                                }else{
                                    isChange = mtHotelGoodsService.dealPrice(days,tj,salePrice,subPrice,redisKeyExpiDays,apiSalePrice,String.valueOf(thisHotelId),goodsId,date,"3",null,has,null,thisTimestampApi,fromJob);
                                }
                            }else{
                                isChange = mtHotelGoodsService.dealPrice(days,tj,salePrice,subPrice,redisKeyExpiDays,apiSalePrice,String.valueOf(thisHotelId),goodsId,date,"3",null,has,null,thisTimestampApi,fromJob);
                            }
                        }else{
                            //最新sale价和上次缓存的sale价不同，则价格发生变化，需要做标准价的对比
                            log.info("111111进入比对 标准价算法，判断价格是否推送");
                            //存缓存的还是接口最新salePrice价。推送给携程的是标准价比对后的价格
                            if(new BigDecimal(salePrice).compareTo(new BigDecimal(libraryPriceBefore))>=0){//存在变化的sale价，且该价大于等于原始标准价，则直接推送
                                isChange = mtHotelGoodsService.dealPrice(days,tj,salePrice,subPrice,redisKeyExpiDays,apiSalePrice,String.valueOf(thisHotelId),goodsId,date,"3",null,has,libraryPriceBefore,thisTimestampApi,fromJob);
                            }else{
                                BigDecimal libraryPriceBig = new BigDecimal(libraryPriceBefore);
                                Integer minLibraryCompare = 8000;//单位分
                                if(null != redisService.get("swmt_min_library_compare")){
                                    minLibraryCompare = (Integer) redisService.get("swmt_min_library_compare");
                                }

                                Integer minLibraryComparePro = 60;
                                if(null != redisService.get(CommonConstants.PRICE_LIBRARY_MIN_COMPARE_PRO)){
                                    minLibraryComparePro = (Integer) redisService.get(CommonConstants.PRICE_LIBRARY_MIN_COMPARE_PRO);
                                }

                                String proTime = (String)redisService.get("swmt_price_today_check_time_pro");
                                if(null == proTime){
                                    proTime = "03,04,05,06";
                                }
                                if(proTime.contains(hourStr)){
                                    if(date.equals(todayOrYest)){
                                        minLibraryComparePro = 80;
                                        log.info("主动 swmt_price_today_check_time_pro 进入 proTime={}，minLibraryComparePro={}",proTime,minLibraryComparePro);
                                    }
                                }

                                String notCheckMinLibraryHour = (String)redisService.get("swmt_library_not_check_min_hour");//多个时间段逗号隔开，当前设置为"11,00,01"
                                if(null != notCheckMinLibraryHour && notCheckMinLibraryHour.contains(hourStr)){
                                    log.info("指定时间段不可推送小标准价，按常规标准价比较 notCheckMinLibraryHour={},hourStr={}",notCheckMinLibraryHour,hourStr);
                                }else{
                                    if(new BigDecimal(libraryPriceBefore).compareTo(new BigDecimal(minLibraryCompare))>0){//标准价大于120时，标准价x0.6 去作为比较价格
                                        libraryPriceBig = libraryPriceBig.multiply(new BigDecimal(minLibraryComparePro).multiply(new BigDecimal(0.01)));
                                        Integer minLibraryLow = (Integer) redisService.get("swmt_minLibraryLow");
                                        if(null == minLibraryLow){
                                            minLibraryLow = 8000;
                                        }
                                        Integer lowPriceCriticalValue = (Integer) redisService.get("swmt_lowPriceCriticalValue");
                                        if(null == lowPriceCriticalValue){
                                            lowPriceCriticalValue = 14000;
                                        }
                                        if(libraryPriceBig.compareTo(BigDecimal.valueOf(minLibraryLow))<0){
                                            if(new BigDecimal(libraryPriceBefore).compareTo(BigDecimal.valueOf(lowPriceCriticalValue))<0){
                                                libraryPriceBig = new BigDecimal(libraryPriceBefore).multiply(new BigDecimal(0.8));
                                            }else{
                                                libraryPriceBig = new BigDecimal(libraryPriceBefore).multiply(new BigDecimal(0.75));
                                            }
                                            log.info("主动job 下标准价过低，再次计算libraryPriceBig={}，libraryPriceBefore={},lowPriceCriticalValue={},minLibraryLow={}",libraryPriceBig.intValue(),libraryPriceBefore.intValue(),lowPriceCriticalValue,minLibraryLow);
                                        }
                                    }
                                }

                                if(BigDecimal.valueOf(salePrice).compareTo(libraryPriceBig)<0){////亏价需要进一步判断，不亏则直接推送携程  changePriceMinTodoLibrary=true时，libraryPriceBig=before标准价
                                    //最新价格低于标准价min 再次判断上一次价格是否也是低于标准价mini，是则需要推送，不是则不推送
                                    if(null == has){
                                        //有标准价，但是【has又是null】，则基本上是删除产品价格日期缓存定时器操作了推送全量。当前推送标准价保证全量价格的推送---》此时推送携程的是中间价60%的标准价
                                        log.info("有标准价，但是has又是null，且最新是亏价，则基本上是删除产品价格日期缓存定时器操作了推送全量 允许推送变化，推送salePrice为标准价mingoodsId={},hotelId={},date={},price={},libraryPrice={},libraryPriceBefore={}",goodsId,thisHotelId,date,salePrice,libraryPriceBig.intValue(),libraryPriceBefore);
                                        //setSalePrice 需要推送的价格 推送为标准价
                                        thisPriceVo.setSalePrice(libraryPriceBig.intValue());
                                        //dealPrice内部更新价格日期缓存还是最新接口价格，日志的remark字段保存最新价格和标准价作为日志
                                        isChange = mtHotelGoodsService.dealPrice(days,tj,salePrice,subPrice,redisKeyExpiDays,apiSalePrice,String.valueOf(thisHotelId),goodsId,date,"3",libraryPriceBig.intValue(),has,libraryPriceBefore,thisTimestampApi,fromJob);
                                    }else{

                                        ////////////20210204 暂时启用这个版本
                                        if(libraryPriceBig.compareTo(new BigDecimal(has))==0) {
                                            if(null == redisService.get("sw_not_push_price_ding_send_"+thisHotelId+"_"+goodsId+"_"+date+"_"+salePrice)){
                                                log.info("[JOB-PRICE-LIBRARY][标准价算法]主动查询价格可能异常最新价格="+salePrice+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+goodsId+"_"+date+" rpInfo="+ GsonUtils.GsonString(result));
                                                SendUtils.dingMsgNotLog("[JOB-PRICE-CHANGE-LIBRARY]主动查询价格VS标准价min较低&上一次价等于标准价min ", DateUtil.getCurrTime()+"不进行推送 最新价格="+salePrice+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+goodsId+"_"+date+" 标准价min："+libraryPriceBig.intValue()+" 标准价："+libraryPriceBefore, MessageEnums.genre.SWITCH_ORDER_ROOM_COMPARE_NOTIFY.getCode(),restTemplate);
                                                redisService.setUnit("sw_not_push_price_ding_send_"+thisHotelId+"_"+goodsId+"_"+date+"_"+salePrice,1,2L,TimeUnit.HOURS);
                                            }else{
                                                log.info("不再推钉钉[JOB-PRICE-LIBRARY]主动查询价格可能异常 产品信息：{}_{}_{} 上一次价格={} 标准价：{} 最新价格={} ",thisHotelId,goodsId,date,has,libraryPriceBig.intValue(),salePrice);
                                            }
                                            //主动无变化日志 异步还是保存变化日志 【当前低于标准价mini】  不推送携程
                                            isChange = false;
                                        }else{
                                            //true   最新价为低于标准价或标准价mini 判断上一次价格比标准价ormini低，需要推送改价
                                            //有标准价，但是has又是null，则基本上是删除产品价格日期缓存定时器操作了推送全量。当前推送标准价保证全量价格的推送---》此时推送携程的是中间价60%的标准价
                                            log.info("有标准价，而且has上一次价格不等于标准价由于最新价低于标准价，当前需更新has推送改价为标准价min，goodsId={},hotelId={},date={},price={},libraryPrice={},libraryPriceBefore={}",goodsId,thisHotelId,date,salePrice,libraryPriceBig.intValue(),libraryPriceBefore);
                                            //setSalePrice 需要推送的价格 推送为标准价
                                            thisPriceVo.setSalePrice(libraryPriceBig.intValue());
                                            //dealPrice内部更新价格日期缓存还是最新接口价格，日志的remark字段保存最新价格和标准价作为日志
                                            isChange = mtHotelGoodsService.dealPrice(days,tj,salePrice,subPrice,redisKeyExpiDays,apiSalePrice,String.valueOf(thisHotelId),goodsId,date,"3",libraryPriceBig.intValue(),has,libraryPriceBefore,thisTimestampApi,fromJob);
                                            SendUtils.dingMsgNotLog("[JOB-PRICE-CHANGE-LIBRARY][推送]主动查询价格VS标准价min较低 ", DateUtil.getCurrTime()+"上一次价格不等于标准价min，当前推送更新价为标准价min 最新价格="+salePrice+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+goodsId+"_"+date+" 标准价min："+libraryPriceBig.intValue()+" 标准价："+libraryPriceBefore, MessageEnums.genre.SWITCH_ORDER_ROOM_COMPARE_NOTIFY.getCode(),restTemplate);
                                        }

                                    }
                                }else{
                                    isChange = mtHotelGoodsService.dealPrice(days,tj,salePrice,subPrice,redisKeyExpiDays,apiSalePrice,String.valueOf(thisHotelId),goodsId,date,"3",null,has,libraryPriceBefore,thisTimestampApi,fromJob);
                                }
                            }


                        }
                    }
                }
                //endend----------------结束合理价判断

                //Boolean isChange = mtHotelGoodsService.checkMtGoodsChange(String.valueOf(thisHotelId),goodsId,date,salePrice,"room_price","3",result);
                if(isChange){
                    //log.info("校验返回存在变化{}，一个产品一个日期价格发生变化价格产品信息为{}",timestamp,key+"_"+date+"_"+salePrice+",");
                    //该产品该日期的价格发送改变
                    if(null != tj){
                        thisPriceVo.setSalePrice(BigDecimal.valueOf(thisPriceVo.getSalePrice()).add(BigDecimal.valueOf(tj)).intValue());
                        log.info("最终价格，主动查询调价酒店，进行追加金额：hotelId={},tj={},thisPriceVo={}",thisHotelId,tj,thisPriceVo.getSalePrice());
                    }
                    String swPriceKey = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_PRICE_JOB+thisHotelId+"_"+goodsId+"_"+date;;
                    redisTemplate.opsForValue().set(swPriceKey,thisPriceVo.getSalePrice(),Math.abs(days)+2, TimeUnit.DAYS);//供检测功能使用
                    thisPriceVo.setCompare(returnThisHotelCompare);//携程需要字段，push队列VO使用
                    oneGoodsChangeAboutDatePriceMap.put(String.valueOf(goodsId)+"_"+date,thisPriceVo);
                }
            }
        }
        return  oneGoodsChangeAboutDatePriceMap;
    }


    /**
     * 校验某个 产品日期 是否发生改变
     * @param hourStr
     * @param result
     * @param thisTimestampApi
     * @return
     */
    @Override
    public Map<String,Object> commonCheckOneGoodsDate(String todayOrYest, String mtDate, String hourStr, String result, String thisTimestampApi,
                                                      MtHotelGoodsPriceBaseDetailVo thisGoodsOneChangePriceDate, MtHotelGoodsCallbackVo oneGoods, Integer fromJob){
        Integer apiSalePrice = thisGoodsOneChangePriceDate.getSalePrice();
        String thisHotelId = oneGoods.getHotelId();
        String goodsId=oneGoods.getGoodsId();
        Map<String,Object> returnMap = new HashMap<>();
        Boolean returnTodo = true;
        Integer returnThisHotelCompare = 0;
        Integer thisPriceOrLibrary = apiSalePrice;//当前价格
        String priceMemark = thisGoodsOneChangePriceDate.getPriceRemark();//当前价格

        log.info("commonCheckOneGoodsDate 校验价格日期规则方法 进入 goodsId={},thisHotelId={},hourStr={},result={},thisTimestampApi={},oneGoods={}",goodsId,thisHotelId,hourStr);
        Integer redisStatusDays = (Integer)redisService.get(CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_STATUS_HEAD+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate());//载入新一天时，可能堆积，若推送了价格还没推送房态携程也会开房，这时候会造成延时单
        if(ObjectUtils.isEmpty(redisStatusDays)){
            log.info("异步价格 房态缓存为空,当前跳过该次价格判断等待下一轮 goodsId={},thisHotelId={},date={}",oneGoods.getGoodsId(),thisHotelId,thisGoodsOneChangePriceDate.getDate());
            returnTodo = false;
            returnMap.put("todo",returnTodo);
            returnMap.put("thisHotelCompare",returnThisHotelCompare);
            returnMap.put("thisPriceOrLibrary",thisPriceOrLibrary);
            return returnMap;//continue
        }

        if(new BigDecimal(thisPriceOrLibrary).compareTo(new BigDecimal(5000))<0){//在has前设置
            log.info("异步价格小于50，当前调整为50，hotelId={},goodsId={}",thisHotelId,oneGoods.getGoodsId());
            thisPriceOrLibrary = 5000;
        }

        String redisHotelGoodsKeyExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_PRICE_HEAD+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate();
        Integer has = (Integer)redisService.get(redisHotelGoodsKeyExpiDays);//上一次价格
                                            /*if(new BigDecimal(has).compareTo(new BigDecimal(thisPriceOrLibrary))==0){//上一次价格和当前最新价格一样 则没有变化 不需要推送---》》》异步暂时不做这个判断 都过，只是要判断标准价
                                                returnTodo = false;
                                            }*/

        if(!ObjectUtils.isEmpty(has) && new BigDecimal(thisPriceOrLibrary).compareTo(new BigDecimal(has))>0){
            log.info("异步callback涨价了推送returnThisHotelCompare=1hotelId={},goodsId={},date={}",thisHotelId,oneGoods.getGoodsId(),thisGoodsOneChangePriceDate.getDate());
            returnThisHotelCompare = 1;
        }

        String checkGtPriceHourNot = (String)redisService.get("swmt_check_gt_price_hour_not");//多个时间段逗号隔开，当前设置为"00,01":在这段时间主动查询的价格不推送降价和上一次价格相比
        if(null != checkGtPriceHourNot && checkGtPriceHourNot.contains(hourStr)){
            if(new BigDecimal(has).compareTo(new BigDecimal(thisPriceOrLibrary))==0){//上一次价格和当前最新价格一样 则没有变化 不需要推送---》》》异步暂时不做这个判断 都过，只是要判断标准价-->特殊时间段做这个判断
                returnTodo = false;
            }
            if(returnTodo){
                if(null != has && BigDecimal.valueOf(thisPriceOrLibrary).compareTo(new BigDecimal(has))<0){
                    log.info("callback异步根据上一次价格，指定时间段涨价可推送，降价不推送 checkGtPriceHour={},hourStr={},thisHotelId={},goodsId={},date={}",checkGtPriceHourNot,hourStr,thisHotelId,oneGoods.getGoodsId(),thisGoodsOneChangePriceDate.getDate());
                    returnTodo = false;
                }
            }
        }

        //5天变成售卖4天
        String closeThisDateRedisNormal = (String)redisService.get("normal_close_this_date");//yyyy-MM-dd
        if(!ObjectUtils.isEmpty(closeThisDateRedisNormal)){
            //判断是否普通酒店
            if(closeThisDateRedisNormal.equals(thisGoodsOneChangePriceDate.getDate())){
                Boolean isVip = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_VIP,thisHotelId);
                if(!isVip){
                    String redisKeyStatusExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_STATUS_HEAD+thisHotelId+"_"+goodsId+"_"+thisGoodsOneChangePriceDate.getDate();//美团异步推送的缓存酒店+产品+日期
                    Integer hasStatus = (Integer)redisTemplate.opsForValue().get(redisKeyStatusExpiDays);
                    if(null != hasStatus && hasStatus == 0){
                        returnTodo = false;
                    }else{
                        if(new BigDecimal(has).compareTo(new BigDecimal(thisPriceOrLibrary))==0){//上一次价格和当前最新价格一样 则没有变化 不需要推送---》》》异步暂时不做这个判断 都过，只是要判断标准价-->特殊时间段做这个判断
                            returnTodo = false;
                        }
                        if(returnTodo){
                            if(null != has && BigDecimal.valueOf(thisPriceOrLibrary).compareTo(new BigDecimal(has))<0){
                                log.info("callback NORMAL 减少售卖天数该日降价不推送 checkGtPriceHour={},hourStr={},thisHotelId={},goodsId={},date={}",checkGtPriceHourNot,hourStr,thisHotelId,oneGoods.getGoodsId(),thisGoodsOneChangePriceDate.getDate());
                                returnTodo = false;
                            }
                        }
                    }
                }
            }
        }else{
            String closeThisDateRedisVip = (String)redisService.get("vip_close_this_date");//yyyy-MM-dd
            if(!ObjectUtils.isEmpty(closeThisDateRedisVip)){
                if(closeThisDateRedisVip.equals(thisGoodsOneChangePriceDate.getDate())){
                    //判断是否普通酒店
                    Boolean isVip = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_VIP,thisHotelId);
                    if(isVip){
                        String redisKeyStatusExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_STATUS_HEAD+thisHotelId+"_"+goodsId+"_"+thisGoodsOneChangePriceDate.getDate();//美团异步推送的缓存酒店+产品+日期
                        Integer hasStatus = (Integer)redisTemplate.opsForValue().get(redisKeyStatusExpiDays);
                        if(null != hasStatus && hasStatus == 0){
                            returnTodo = false;
                        }else{
                            if(new BigDecimal(has).compareTo(new BigDecimal(thisPriceOrLibrary))==0){//上一次价格和当前最新价格一样 则没有变化 不需要推送---》》》异步暂时不做这个判断 都过，只是要判断标准价-->特殊时间段做这个判断
                                returnTodo = false;
                            }
                            if(returnTodo){
                                if(null != has && BigDecimal.valueOf(thisPriceOrLibrary).compareTo(new BigDecimal(has))<0){
                                    log.info("callback VIP 减少售卖天数该日降价不推送 checkGtPriceHour={},hourStr={},thisHotelId={},goodsId={},date={}",checkGtPriceHourNot,hourStr,thisHotelId,oneGoods.getGoodsId(),thisGoodsOneChangePriceDate.getDate());
                                    returnTodo = false;
                                }
                            }
                        }
                    }
                }
            }
        }

        if(returnTodo){
            Integer libraryPriceBefore = null;
            if(null == redisService.get("swmt_library_price_close")){
                libraryPriceBefore = (Integer) redisService.get(MeituanConstants.REDIS_ONE_GOODS_PRICE_LIBRARY_NEW+thisHotelId+"_"+oneGoods.getGoodsId());//标准价
            }

            if(null == libraryPriceBefore){
                if(null != has){
                    log.info("进入比对 比例低价算法，判断价格是否推送");
                    Integer minPrice = 20000;//单位分
                    if(null != redisService.get("sw_price_check_change_min")){
                        minPrice =(Integer) redisService.get("sw_price_check_change_min");
                    }

                    Double pro =  0.6;
                    if(null != redisService.get("sw_price_check_change_min_pro")){//40
                        pro =new BigDecimal((Integer) redisService.get("sw_price_check_change_min_pro")).multiply(new BigDecimal(0.01)).doubleValue();
                    }

                    if(new BigDecimal(thisPriceOrLibrary).compareTo(new BigDecimal(minPrice))<=0 && new BigDecimal(has).multiply(new BigDecimal(pro)).compareTo(new BigDecimal(thisPriceOrLibrary))>0){
                        if(null == redisService.get("sw_not_push_price_ding_send_"+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+"_"+thisPriceOrLibrary)){
                            log.info("[CALLBACK-PRICE-TASK][比例低价算法]异步价格可能异常最新价格="+thisPriceOrLibrary+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate());
                            SendUtils.dingMsgNotLog("[CALLBACK-PRICE-CHANGE-CHECK]异步价格变化浮动可能异常，人工确认 ", DateUtil.getCurrTime()+" 最新价格="+thisPriceOrLibrary+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+" 比例底价："+pro+"_"+minPrice, MessageEnums.genre.SWITCH_ORDER_ROOM_COMPARE_NOTIFY.getCode(),restTemplate);
                            redisService.setUnit("sw_not_push_price_ding_send_"+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+"_"+thisPriceOrLibrary,1,2L,TimeUnit.HOURS);
                        }else{
                            log.info("不再推钉钉[CALLBACK-PRICE-TASK]异步价格可能异常最新价格="+thisPriceOrLibrary+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate());
                        }
                        //主动无变化日志 异步还是保存变化日志 虽然没有推送携程
                        returnTodo = false;
                    }
                }
            }else{
                //存缓存的还是接口最新salePrice价。推送给携程的是标准价比对后的价格
                log.info("111111进入比对 标准价算法，判断价格是否推送");
                if(new BigDecimal(thisPriceOrLibrary).compareTo(new BigDecimal(libraryPriceBefore))>=0){//存在变化的sale价，且该价大于等于原始标准价，则直接推送
                    //returnTodo = true;
                }else{
                    BigDecimal libraryPriceBig = new BigDecimal(libraryPriceBefore);
                    Integer minLibraryCompare = 6000;//单位分
                    if(null != redisService.get("swmt_min_library_compare")){
                        minLibraryCompare = (Integer) redisService.get("swmt_min_library_compare");
                    }

                    Integer minLibraryComparePro = 60;
                    if(null != redisService.get("swmt_min_library_compare_pro")){
                        minLibraryComparePro = (Integer) redisService.get("swmt_min_library_compare_pro");
                    }
                    String proTime = (String)redisService.get("swmt_price_today_check_time_pro");
                    if(null == proTime){
                        proTime = "03,04,05,06";
                    }
                    if(proTime.contains(hourStr)){
                        if(mtDate.equals(todayOrYest)){
                            minLibraryComparePro = 80;
                            log.info("异步 swmt_price_today_check_time_pro 进入 proTime={}，minLibraryComparePro={}",proTime,minLibraryComparePro);
                        }
                    }

                    String notCheckMinLibraryHour = (String)redisService.get("swmt_library_not_check_min_hour");//多个时间段逗号隔开，当前设置为"00"
                    if(null != notCheckMinLibraryHour && notCheckMinLibraryHour.contains(hourStr)){
                        log.info("指定时间段不可推送小标准价，按常规标准价比较 notCheckMinLibraryHour={},hourStr={}",notCheckMinLibraryHour,hourStr);
                    }else{
                        if(new BigDecimal(libraryPriceBefore).compareTo(new BigDecimal(minLibraryCompare))>0){//标准价大于120时，标准价x0.6 去作为比较价格
                            libraryPriceBig = libraryPriceBig.multiply(new BigDecimal(minLibraryComparePro).multiply(new BigDecimal(0.01)));
                            Integer minLibraryLow = (Integer) redisService.get("swmt_minLibraryLow");
                            if(null == minLibraryLow){
                                minLibraryLow = 8000;
                            }
                            Integer lowPriceCriticalValue = (Integer) redisService.get("swmt_lowPriceCriticalValue");
                            if(null == lowPriceCriticalValue){
                                lowPriceCriticalValue = 14000;
                            }
                            if(libraryPriceBig.compareTo(BigDecimal.valueOf(minLibraryLow))<0){
                                if(new BigDecimal(libraryPriceBefore).compareTo(BigDecimal.valueOf(lowPriceCriticalValue))<0){
                                    libraryPriceBig = new BigDecimal(libraryPriceBefore).multiply(new BigDecimal(0.8));
                                }else{
                                    libraryPriceBig = new BigDecimal(libraryPriceBefore).multiply(new BigDecimal(0.75));
                                }
                                log.info("callback 下标准价过低，再次计算libraryPriceBig={}，libraryPriceBefore={},lowPriceCriticalValue={},minLibraryLow={}",libraryPriceBig.intValue(),libraryPriceBefore.intValue(),lowPriceCriticalValue,minLibraryLow);
                            }
                        }
                    }
                    if(BigDecimal.valueOf(thisPriceOrLibrary).compareTo(libraryPriceBig)<0){//亏价需要进一步判断，不亏则直接推送携程

                        //价格低于标准价（或标准价的60%）  加入队列，定时器针对这些酒店产品重新跑一下标准价，并且查询的是本周的数据库表，不是上周。
                                                        /*if(null == redisService.get("swmt_queue_update_library_pirce_this_week_this_task"+thisHotelId) && null == redisService.get("swmt_queue_update_library_pirce_this_week_has"+thisHotelId)){//定时器处理过一次就set失效时间为半天
                                                            redisService.setUnit("swmt_queue_update_library_pirce_this_week_this_task",1,4L,TimeUnit.HOURS);
                                                            String thisWeek = hotel.base.oversea.utils.DateUtil.dayForWeek(hotel.base.oversea.utils.DateUtil.getCurrTime());
                                                            if(!thisWeek.equals("周一") && !thisWeek.equals("周六") && !thisWeek.equals("周日")){
                                                                log.info("当前非周一周六周日，售价低于标准价重新计算标准价计算时间为本周昨天一天goodsId={}，thisHotelId={}",oneGoods.getGoodsId(),thisHotelId);
                                                                //价格低于标准价（或标准价的60%）  加入队列，定时器针对这些酒店产品重新跑一下标准价，并且查询的是本周的数据库表，不是上周。
                                                                redisService.lPush("swmt_queue_update_library_pirce_this_week",thisHotelId);
                                                            }
                                                        }*/
                        //最新价格低于标准价min 再次判断上一次价格是否也是低于标准价mini，是则需要推送，不是则不推送
                        if(null == has){
                            //有标准价，但是【has又是null】，则基本上是删除产品价格日期缓存定时器操作了推送全量。当前推送标准价保证全量价格的推送---》此时推送携程的是中间价60%的标准价
                            log.info("有标准价，但是has又是null，且最新是亏价，则基本上是删除产品价格日期缓存定时器操作了推送全量 允许推送变化，推送salePrice为标准价min goodsId={},hotelId={},date={},price={}，libraryPrice={},libraryPriceBefore={}",oneGoods.getGoodsId(),thisHotelId,thisGoodsOneChangePriceDate.getDate(),thisPriceOrLibrary,libraryPriceBig.intValue(),libraryPriceBefore);
                            priceMemark = apiSalePrice+"_"+thisPriceOrLibrary+"="+libraryPriceBig.intValue()+"_"+libraryPriceBefore;//作为日志：查询到的是thisPrice但是推送的是libraryPrice，日志保存price字段还是接口的最新价格，标准价保存在remark里
                            thisPriceOrLibrary = libraryPriceBig.intValue();//推送的价格设置为标准价
                        }else{
                            if(libraryPriceBig.compareTo(new BigDecimal(has))==0) {
                                if(null == redisService.get("sw_not_push_price_ding_send_"+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+"_"+thisPriceOrLibrary)){
                                    log.info("[CALLBACK-PRICE-LIBRARY][标准价算法]异步价格可能异常最新价格="+thisPriceOrLibrary+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate());
                                    SendUtils.dingMsgNotLog("[CALLBACK-PRICE-CHANGE-LIBRARY]异步价格VS标准价较低&上一次价等于标准价min ", DateUtil.getCurrTime()+"不进行推送 最新价格="+thisPriceOrLibrary+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+" 标准价mini："+libraryPriceBig.intValue()+" 标准价："+libraryPriceBefore, MessageEnums.genre.SWITCH_ORDER_ROOM_COMPARE_NOTIFY.getCode(),restTemplate);
                                    redisService.setUnit("sw_not_push_price_ding_send_"+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+"_"+thisPriceOrLibrary,1,2L,TimeUnit.HOURS);
                                }else{
                                    log.info("不再推钉钉[CALLBACK-PRICE-LIBRARY]异步价格可能异常最新价格="+thisPriceOrLibrary+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+" 标准价："+libraryPriceBig.intValue());
                                }
                                //异步价格一般都是要推送携程不阻拦，但需判断标准价，【当前低于标准价mini】， 保存变化日志 不推送携程
                                returnTodo = false;
                            }else{
                                //true   上一次价格比标准价低，需要推送改价---》此时推送携程的是中间价60%的标准价或原始标准价
                                SendUtils.dingMsgNotLog("[CALLBACK-PRICE-CHANGE-LIBRARY][推送]主动查询价格VS标准价min较低 ", DateUtil.getCurrTime()+"上一次价格不等于标准价min，当前推送更新价为标准价min 最新价格="+thisPriceOrLibrary+" 上一次价格="+has+" 产品信息："+thisHotelId+"_"+oneGoods.getGoodsId()+"_"+thisGoodsOneChangePriceDate.getDate()+" 标准价min："+libraryPriceBig.intValue()+" 标准价："+libraryPriceBefore, MessageEnums.genre.SWITCH_ORDER_ROOM_COMPARE_NOTIFY.getCode(),restTemplate);
                                log.info("有标准价，而且has上一次价格不等于标准价由于最新价低于标准价，当前需更新has推送改价为标准价goodsId={},hotelId={},date={},price={}，libraryPrice={},libraryPriceBefore={}",oneGoods.getGoodsId(),thisHotelId,thisGoodsOneChangePriceDate.getDate(),thisPriceOrLibrary,libraryPriceBig.intValue(),libraryPriceBefore);
                                priceMemark = apiSalePrice+"_"+thisPriceOrLibrary+"="+libraryPriceBig.intValue()+"_"+libraryPriceBefore;//作为日志：查询到的是thisPrice但是推送的是libraryPrice，日志保存price字段还是接口的最新价格，标准价保存在remark里
                                thisPriceOrLibrary = libraryPriceBig.intValue();//推送的价格设置为标准价
                            }
                        }
                    }
                }
            }
        }
        returnMap.put("todo",returnTodo);
        returnMap.put("thisHotelCompare",returnThisHotelCompare);
        returnMap.put("thisPriceOrLibrary",thisPriceOrLibrary);
        returnMap.put("priceMemark",priceMemark);
        return returnMap;
    }
}
